﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.IO;
using System.Threading;

namespace proxyTest
{
    class TestResault
    {
        public int timeCost;
        public string proxySrv;
        public int port;
        public string url;
        public TestResault()
        {
            timeCost = 0;
            proxySrv = "127.0.0.1";
            port = 80;
            url = "www.microsoft.com/";
        }
        public override string ToString()
        {
            StringWriter sw = new StringWriter();
            sw.WriteLine(timeCost + "\t" + proxySrv + ":" + port + "\t" + url);
            return sw.ToString();
        }
    }
    class BatchProxyTester
    {
        private ArrayList proxySrvLst;
        public ArrayList testResults;
        private string testURL;
        private Thread[] threads;
        private bool[] finished;
        public bool IsTestFinished(int i)
        {
            return finished[i];
        }
        public BatchProxyTester(ArrayList _proxySrvLst, string _testURL)
        {
            int i = 0;
            proxySrvLst = _proxySrvLst;
            testURL = _testURL;
            threads = new Thread[_proxySrvLst.Count];
            finished = new bool[_proxySrvLst.Count];
            testResults = new ArrayList(_proxySrvLst.Count);
            for (i = 0; i < _proxySrvLst.Count; i++)
            {
                testResults.Add(new TestResault());
            }
        }
        BatchProxyTester() { }
        public void TestAProxy(object o)
        {
            int i = (int)o;
            finished[i] = false;
            ProxyUrl proxyUrl = new ProxyUrl((string)proxySrvLst[i]);
            TestResault res = new TestResault();
            res.timeCost = ProxyTester.TestProxy("http://" + testURL, proxyUrl.proxy, proxyUrl.port);
            res.proxySrv = proxyUrl.proxy;
            res.port = proxyUrl.port;
            res.url = testURL;
            testResults[i] = res;
            finished[i] = true;
        }
        public void Test()
        {
            int i = 0;
            for (i = 0; i < proxySrvLst.Count; i++)
            {
                threads[i] = new Thread(new ParameterizedThreadStart(TestAProxy));
                threads[i].Start(i);
            }
        }
    }
    class Program
    {
        static string version = "0.1";
        static string defaultUrl = "www.microsoft.com";
        static private void ShowHelp()
        {
            Console.WriteLine("proxyTest" + version + ": Test speed of http/socket proxy server");
            Console.WriteLine("Usage: proxyTest [Proxy:port [username passwd] [-u url]][-f proxylistfile [outputfile]][-h][-v]");
            Console.WriteLine("Example:");
            Console.WriteLine("\tproxyTest 10.1.0.12:80");
            Console.WriteLine("\tproxyTest 10.1.0.12:80 user passwd");
            Console.WriteLine("\tproxyTest 10.1.0.12:80 -u" + defaultUrl);
            Console.WriteLine("\tproxyTest -f proxylst.txt");
            Console.WriteLine("\tproxyTest -f proxylst.txt resault.txt");
            Console.WriteLine("Any problems email to: xingzhe20011@sina.com");
        }
        static TestResault TestProxy(string url) //url is like 10.1.0.12:80 
        {
            ProxyUrl proxyUrl = new ProxyUrl(url);
            TestResault res = new TestResault();
            res.timeCost = ProxyTester.TestProxy("http://" + defaultUrl, proxyUrl.proxy, proxyUrl.port);
            res.proxySrv = proxyUrl.proxy;
            res.port = proxyUrl.port;
            res.url = defaultUrl;
            return res;
        }
        static ArrayList LoadLstFromFile(string filename)
        {
            ArrayList lst = new ArrayList();
            StreamReader sr = new StreamReader(filename);
            string item;
            while ((item = sr.ReadLine()) != null)
            {
                lst.Add(item);
            }
            return lst;

        }

        static void Main(string[] args) 
        { 
            //string  
            //ArrayList proxySrvLst = new ArrayList(); 
            if (args.Length == 0) 
            { 
                ShowHelp(); 
                 
                return; 
            } 
            else if (args[0] == "-h") 
            { 
                ShowHelp(); 
                return; 
            } 
            else if (args[0] == "-v") 
            { 
                Console.WriteLine("proxyTest v" + version); 
            } 
            else if (args.Length > 1 && args[0] == "-f") 
            { 
                try 
                { 
 
 
                    ArrayList srvlst = LoadLstFromFile(args[1]); 
                    BatchProxyTester bt = new BatchProxyTester(srvlst, defaultUrl); 
                    bt.Test(); 
                    int[] finished = new int[bt.testResults.Count]; 
                    bool[] register_finished = new bool[bt.testResults.Count]; 
                    for (int k = 0; k<bt.testResults.Count; k++) register_finished[k] = false; 
                    int i = 0, j = 0; 
 
                    while (i != bt.testResults.Count) 
                    { 
                        int lasti = i; 
                        j = 0; 
 
                        for (j = 0; j < bt.testResults.Count; j++) 
                        { 
                            if (bt.IsTestFinished(j)) 
                            { 
                                if (!register_finished[j]) 
                                { 
                                    Console.WriteLine(((TestResault)(bt.testResults[j])).ToString()); 
                                    register_finished[j] = true; 
                                    i++; 
                                } 
                            } 
 
                        } 
                        if (i != lasti) Console.WriteLine("There are " + i + " tests finished,still has " + (bt.testResults.Count - i)); 
                        lasti = i; 
                    } 
                    //foreach (TestResault res in bt.testResults) 
                    //{ 
                    //    Console.WriteLine(res.ToString()); 
                    //} 
                } 
                catch (Exception exception) 
                { 
                    Console.WriteLine(exception.Message); 
                } 
 
            } 
            else if (args[0][0] == '-') 
            { 
                ShowHelp(); 
                return; 
            } 
            else if (args.Length >= 1) 
            { 
                if (args[1] == "-u" && args[2].Length > 0) 
                { 
                    defaultUrl = args[2]; 
                } 
                TestResault res = new TestResault(); 
                res = TestProxy(args[0]); 
                Console.WriteLine(res.ToString()); 
            } 
            else 
            { 
                ShowHelp(); 
                return; 
            } 
             
        }
    }
}
